/* 2014/10/24 */
package com.cosmos.quartz.control.Db;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;

import com.cosmos.quartz.control.AgentControlIgnore;
import com.cosmos.quartz.control.AgentControlService;
import com.cosmos.quartz.control.ControlRequest;
import com.cosmos.quartz.control.ControlResponse;
import com.cosmos.quartz.control.QuartzController;

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@AgentControlIgnore
public class DbQuartzControlJob implements Job {

	private static final Logger log = Logger.getLogger(DbQuartzControlJob.class.getSimpleName());
	
	private static final String agentName;
	
	static {
		String packageName = DbQuartzControlJob.class.getPackage().getName();
		
		String baseName = getStringFromSystemProperty(packageName + ".properties", "control");	
		ResourceBundle bundle = null;
		try {						
			bundle = ResourceBundle.getBundle(baseName);			
		} catch (MissingResourceException ex) {
			log.error("Get resouce bundle \"" + baseName + "\" failed. Load configure from system property.", ex);
		}
		
		if (bundle != null) {
			agentName = getStringFromResourceBundle(bundle, "AgentName", "DefaultAgent");
		} else {
			agentName = getStringFromSystemProperty(packageName + ".agentName", "DefaultAgent");
		}
	}
	
	private static String getStringFromResourceBundle(ResourceBundle bundle, String key, String defaultValue) {
		String value = defaultValue;
		if (bundle != null) {
			try {
				value = bundle.getString(key);
				log.info("Get string form resource bundle. Key: " + key + ", value: " + value);
			} catch (MissingResourceException ex) {
				log.error("Get string from resource bundle failed. Key: " + key, ex);
				log.info("Use default value: " + defaultValue);
			}	
		}
		return value;
	}
	
	private static String getStringFromSystemProperty(String key, String defaultValue) {
		String value = System.getProperty(key);
		if (value != null) {
			log.info("Get string from system property. Key: " + key + ", value: " + value);
		} else {
			log.error("Get string from system property failed. Key: " + key);
			
			value = defaultValue;
			log.info("Use default value: " + defaultValue);
		}
		return value;
	}
	
	public void execute(JobExecutionContext context) throws JobExecutionException {
		
		List<DbControlRequest> requests = receiveRequests();
		if (requests == null || requests.size() == 0) {
			return;
		}
		log.info("Requests are received.");
		
		QuartzController controller = new QuartzController();
		List<DbControlResponse> responses = new ArrayList<DbControlResponse>(requests.size());
		for (DbControlRequest request : requests) {
			ControlRequest baseRequest = request.toBaseRequest();
			ControlResponse baseResponse = controller.process(baseRequest);
			DbControlResponse response = new DbControlResponse(baseResponse);
			
			response.setRequestId(request.getId());
			response.setAgent(agentName);
			
			responses.add(response);
		}
		
		sendResponses(responses);
		log.info("Responses are sent.");
	}
	
	protected List<DbControlRequest> receiveRequests() {
		List<DbControlRequest> requestList = null;
		try {
			requestList = AgentControlDao.$.retrieveACRequestNoResponseByAgent(agentName, true,
					AgentControlService.getValidRequestStartTime());
		} catch (SQLException ex) {
			log.error(ex);
		}
		return requestList;
	}
	
	protected void sendResponses(List<DbControlResponse> responses) {
		try {
			AgentControlDao.$.insertBatchACResponse(responses);
		} catch (SQLException ex) {
			log.error(ex);
		}		
	}

}
